---
icon: FormulaIcon
---

import { compileMdx } from 'nextra/compile'
import {
  Callout,
  MathJax,
  MathJaxContext,
  Steps,
  Tabs
} from 'nextra/components'
import { MDXRemote } from 'nextra/mdx-remote'

{/* <link rel="stylesheet"> is unsupported in Metadata API https://nextjs.org/docs/app/api-reference/functions/generate-metadata#unsupported-metadata */}

<link
  rel="stylesheet"
  href="https://cdn.jsdelivr.net/npm/katex/dist/katex.css"
/>

# LaTeX

Nextra can use [KaTeX](https://katex.org) to pre-render LaTeX expressions
directly in MDX or [MathJax](https://mathjax.org) to dynamically render math in
the browser.

## Setup

<Steps>

### Enable the `latex` option

By default, LaTeX is disabled. To enable it, you need to set the `latex` option
in your `next.config.mjs` file:

```js filename="next.config.mjs" {4}
import nextra from 'nextra'

const withNextra = nextra({
  latex: true
})

export default withNextra()
```

A value of `true{:js}` will use KaTeX as the math renderer. To explicitly
specify the renderer, you may instead provide an object
`{ renderer: 'katex' }{:js}` or `{ renderer: 'mathjax' }{:js}` as the value to
`latex: ...`.

When enabled, the required CSS and fonts will be automatically included in your
site, and you can start writing math expressions by enclosing inline math in
`$...$` or display math in a `math`-labeled fenced code block:

````mdx
```math
\int x^2
```
````

### Apply styles

<Callout type="warning">
  This is applicable only to KaTeX as the math renderer.
</Callout>

<Tabs items={['Import CSS from `katex` package', 'Load CSS from CDN']}>
<Tabs.Tab>
1. Install the `katex` package

```bash npm2yarn
npm i katex
```

2. Import CSS in the root layout

```js filename="app/layout.jsx"
import 'katex/dist/katex.min.css'
```

</Tabs.Tab>
<Tabs.Tab>
Add `<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/katex/dist/katex.css" />{:jsx}`
inside `<head>` element in your root `layout` file since `<link rel="stylesheet" />{:jsx}`
[isn't supported with Next.js Metadata API](https://nextjs.org/docs/app/api-reference/functions/generate-metadata#unsupported-metadata).

Alternatively, you can include `<link rel="stylesheet" />{:jsx}` directly in
your MDX file:

````mdx filename="katex.mdx"
<link
  rel="stylesheet"
  href="https://cdn.jsdelivr.net/npm/katex/dist/katex.css"
/>

# My page with single usage of KaTeX

```math
\int_2^3x^3\,\mathrm{d}x
```
````

</Tabs.Tab>
</Tabs>
</Steps>

## Example

For example, the following Markdown code:

````md filename="page.md"
The **Pythagorean equation** is $a=\sqrt{b^2 + c^2}$ and the quadratic formula:

```math
x=\frac{-b\pm\sqrt{b^2-4ac}}{2a}
```
````

will be rendered as:

<div className="mt-6 rounded-xl border p-4 nextra-border">
The **Pythagorean equation** is $a=\sqrt{b^2 + c^2}$ and the quadratic formula:

```math
x=\frac{-b\pm\sqrt{b^2-4ac}}{2a}
```

</div>

You can still use [Markdown and MDX syntax](../guide/markdown) in the same line
as your LaTeX expression.

> [!TIP]
>
> If you want to display `$` in your content instead of rendering it as an
> equation, you can escape it with a backslash (`\`). For example `\$e = mc^2\$`
> will be rendered as \$e = mc^2\$.

## API

### KaTeX

`rehype-katex` is used to pre-render LaTeX expressions in your content. You can
pass supported [KaTeX options](https://katex.org/docs/options) via the `options`
key in your Nextra config. For example, to add a macro `\RR` that renders as
`\mathbb{R}` you could use the following configuration.

```js filename="next.config.mjs" {4-8}
const withNextra = nextra({
  latex: {
    renderer: 'katex',
    options: {
      macros: {
        '\\RR': '\\mathbb{R}'
      }
    }
  }
})
```

See [KaTeX's documentation](https://katex.org/docs/supported) for a list of
supported commands.

### MathJax

When MathJax is enabled (by setting `latex: { renderer: 'mathjax' }{:js}`) math
is rendered on page load via
[`better-react-mathjax`](https://github.com/fast-reflexes/better-react-mathjax)
instead of being pre-rendered. By default, **MathJax is served via the MathJax
CDN** instead of the files being directly included in your site.[^1]

[^1]:
    This can be changed by setting
    [`{ options: { src: ... } }{:js}`](https://github.com/fast-reflexes/better-react-mathjax#src-string--undefined)
    in the Nextra config.

MathJax rendering is enabled by setting `renderer: 'mathjax'{:js}` in your
Nextra config.

```js filename="next.config.mjs" {3}
const withNextra = nextra({
  latex: {
    renderer: 'mathjax'
  }
})
```

You can pass additional options to `better-react-mathjax` via the `options` key
in your Nextra config. The `config: ...` option sets the
[MathJax configuration](https://docs.mathjax.org/en/latest/options/index.html).
However, note that you can only pass serializable options to
`better-react-mathjax` via the `options` key in your Nextra config.[^2]

[^2]:
    To pass non-serializable objects like Functions, you must use the
    `<MathJaxContext config={...} />{:jsx}` component directly in your source.

For example, to configure MathJax to render `\RR` as `\mathbb{R}` you could use
the following configuration.

```js filename="next.config.mjs" {4-12}
const withNextra = nextra({
  latex: {
    renderer: 'mathjax',
    options: {
      config: {
        tex: {
          macros: {
            RR: '\\mathbb{R}'
          }
        }
      }
    }
  }
})
```

#### MathJax CDN

By default, MathJax is served via the MathJax CDN. To serve files from another
location (including locally in your project), you must pass the `src: ...`
option to the latex config. See the
[better-react-mathjax documentation](https://github.com/fast-reflexes/better-react-mathjax#src-string--undefined)
for details about the `src` option. Additionally, you may need to copy the
MathJax distribution into your `/public` folder for it to be served locally.

## KaTeX vs. MathJax

With KaTeX, math is pre-rendered which means flicker-free and faster page loads.
However, KaTeX does not support all the features of MathJax, especially features
related to accessibility.

The following two examples show the same formula rendered with KaTeX (first) and
MathJax (second).

```math
\int_2^3x^3\,\mathrm{d}x
```

<MathJaxExample />

Because of MathJax's accessibility features, the second formula is
tab-accessible and has a context menu that helps screen readers reprocess math
for the visually impaired.

export async function MathJaxExample() {
  const rawMdx = `~~~math
\\int_2^3x^3\\,\\mathrm{d}x
~~~`
  const rawJs = await compileMdx(rawMdx, {
    latex: {
      renderer: 'mathjax',
      options: {
        config: {
          tex: {
            macros: {
              RR: '\\mathbb{R}'
            }
          }
        }
      }
    }
  })
  return (
    <MDXRemote
      compiledSource={rawJs}
      components={{ MathJax, MathJaxContext }}
    />
  )
}
